package org.googlecode.viewt.core.tools.ejb;

import org.apache.velocity.VelocityContext;
import org.googlecode.viewt.core.tools.AbstractVelocityGenerator;
import org.googlecode.viewt.core.tools.JavaSourceParser;
import org.googlecode.viewt.core.tools.LogicDescRepository;

import xjavadoc.SourceClass;
import xjavadoc.XMethod;

public abstract class BaseEJBGenerator extends AbstractVelocityGenerator {
	public static final String CONTEXT_PROP_REPOSITORY = "REPOSITORY";
	public static final String CONTEXT_PROP_UTIL = "UTILITY";
	public static final String CONTEXT_PROP_GENERATOR = "GENERATOR";
	public static final String CONTEXT_PROP_PREFIX = "PREFIX";
	public static final String CONTEXT_PROP_PRJNAME = "PROJECT";
	public static final String CONTEXT_PROP_MODNAME = "MODULE";
	public static final String CONTEXT_PROP_METHODS = "METHODS";
	public static final String CONTEXT_PROP_BSNAME = "BSNAME";
	private LogicDescRepository logicRepository;
	private String bsName;
	private String prePackName;
	private String projectName;
	private String moduleName;
	private XMethod[] methods;
	private String destPath;
	private String fileTemplatePath;

	public BaseEJBGenerator() {
		this.logicRepository = null;

		this.bsName = null;

		this.prePackName = null;

		this.projectName = null;

		this.moduleName = null;

		this.methods = null;

		this.destPath = null;

		this.fileTemplatePath = null;
	}

	public void init(LogicDescRepository logicRepository, String[] incMethods,
			String[] excMethods) throws Exception {
		super.init();
		this.logicRepository = logicRepository;
		SourceClass intClass = logicRepository.getBLInterface();
		this.methods = JavaSourceParser.getMethods(intClass, incMethods,
				excMethods);
	}

	public void performGen() throws Exception {
		if ((this.logicRepository == null) || (this.destPath == null)
				|| (this.bsName == null) || (this.projectName == null)
				|| (this.moduleName == null) || (this.methods == null)) {
			
			System.out.println(this.logicRepository);
			System.out.println(this.destPath);
			System.out.println(this.bsName);
			System.out.println(this.projectName);
			System.out.println(this.moduleName);
			System.out.println(this.methods);
			
			
			
			getLogger().error("Perform generation fail, set environment first");
			throw new Exception("config or enviroment not set");
		}

		VelocityContext context = getContext();
		if (null == context) {
			context = new VelocityContext();
			setContext(context);
		}
		context.put("REPOSITORY", this.logicRepository);
		context.put("UTILITY", new EJBUtil());
		context.put("GENERATOR", this);
		context.put("BSNAME", this.bsName);
		context.put("PREFIX", this.prePackName);
		context.put("PROJECT", this.projectName);
		context.put("MODULE", this.moduleName);
		context.put("METHODS", this.methods);

		setupContext();

		if (needGenerate(this.bsName)) {
			String templateName = getTemplate(this.bsName);
			String outputFile = getOutputFile(this.bsName);
			if ((null == templateName) || ("".equals(templateName))) {
				getLogger().error(
						"Empty template name:" + templateName
								+ ", generation fail");
				throw new Exception("Can not get template for service:"
						+ this.bsName);
			}
			if ((null == outputFile) || ("".equals(outputFile))) {
				getLogger()
						.error(
								"Empty output file:" + outputFile
										+ ", generation fail");
				throw new Exception("Can not get output file for service:"
						+ this.bsName);
			}

			singleOutput(templateName, outputFile);

			getLogger().debug(
					"generate code for service:" + this.bsName + " succeed");
		} else {
			getLogger().debug(
					"need not generate code for service:" + this.bsName
							+ ", bypass");
		}

		cleanContext();

		context.remove("METHODS");
		context.remove("MODULE");
		context.remove("PROJECT");
		context.remove("PREFIX");
		context.remove("BSNAME");
		context.remove("GENERATOR");
		context.remove("UTILITY");
		context.remove("REPOSITORY");

		getLogger().debug("Perform code generation done.");
	}

	public void setRepository(LogicDescRepository logicRepository) {
		this.logicRepository = logicRepository;
	}

	public LogicDescRepository getRepository() {
		return this.logicRepository;
	}

	public void setServiceName(String serviceName) {
		this.bsName = serviceName;
	}

	public String getServiceName() {
		return this.bsName;
	}

	public void setPrePackName(String prePackName) {
		this.prePackName = prePackName;
	}

	public String getPrePackName() {
		return this.prePackName;
	}

	public void setProjectName(String projectName) {
		this.projectName = projectName;
	}

	public String getProjectName() {
		return this.projectName;
	}

	public void setModuleName(String moduleName) {
		this.moduleName = moduleName;
	}

	public String getModuleName() {
		return this.moduleName;
	}

	public void setDestPath(String destPath) {
		this.destPath = destPath;
	}

	public String getDestPath() {
		return this.destPath;
	}

	public void setFileTemplatePath(String fileTemplatePath) {
		this.fileTemplatePath = fileTemplatePath;
	}

	public String getFileTemplatePath() {
		return this.fileTemplatePath;
	}

	public String getPackageTemplatePath() {
		return "resource/template/ejb";
	}

	public abstract String getTemplate(String paramString) throws Exception;

	public abstract String getOutputFile(String paramString) throws Exception;

	public abstract boolean needGenerate(String paramString) throws Exception;

	public abstract void setupContext() throws Exception;

	public abstract void cleanContext() throws Exception;
}